<?php

namespace application\service;

use application\entity\db\CpFunction;
use application\entity\db\CpFunctionGroup;
use application\entity\form\FunctionForm;
use application\entity\Response;
use application\model\CpFunctionGroupModel;
use application\model\CpFunctionModel;
use application\service\BaseService;
use application\util\TextUtil;
use core\entity\Criteria;
use core\entity\Query;
use core\system\Build;
use application\entity\enu\CpFunctionType;

class FunctionService extends BaseService {

    private $cpFunctionModel;
    private $cpFunctionGroupModel;

    public function __construct() {
        $this->cpFunctionModel = new CpFunctionModel();
        $this->cpFunctionGroupModel = new CpFunctionGroupModel();
    }

    /**
     * Danh sách quyền được mapping trên hệ thống
     */
    public function getCpFunctionSystem() {
        $build = new Build();
        $mappings = $build->filter();
        $functions = [];
        foreach ($mappings as $mapping) {
            if (preg_match('/cp\//', $mapping[0])) {
                $functions[$mapping[0]] = [];
            }
        }

        foreach ($functions as $key => $function) {
            $cpFunction = explode(".html", $key);
            $cpFunction = str_replace("/", "service/", $cpFunction[0]);
            $cpFunction = str_replace("/", "\/", $cpFunction);
            foreach ($mappings as $mapping) {
                if (!preg_match('/cp\//', $mapping[0]) && preg_match('/' . $cpFunction . '/', $mapping[0])) {
                    $functions[$key][] = $mapping[0];
                }
            }
        }
        return $functions;
    }

    /**
     * Danh sách nhóm quyền
     * @return type
     */
    public function getCpFunctionGroup() {
        $cri = new Criteria();
        $sort = new \core\entity\Sort("position", \core\entity\Sort::ASC);
        $query = new Query($cri);
        $query->withSort($sort);
        return $this->cpFunctionGroupModel->ifind($query);
    }

    /**
     * Danh sách chức năng
     * @return type
     */
    public function getCpFunctions() {
        $cri = new Criteria();
        $sort = new \core\entity\Sort("position", \core\entity\Sort::ASC);
        $query = new Query($cri);
        $query->withSort($sort);
        return $this->cpFunctionModel->ifind($query);
    }

    /**
     * Thêm mới chức năng
     * @param FunctionForm $form
     * @return Response
     */
    public function add(FunctionForm $form) {
        if ($form == null) {
            return new Response(false, "Thông tin truyền chưa chính xác");
        }
        $form->id = '';
        $error = array();
        if (TextUtil::getVariable($form, "name") == null) {
            $error["name"] = "Tên chức năng không được để trống";
        }
        if (TextUtil::getVariable($form, "groupId") == null && TextUtil::getVariable($form, "groupName") == null) {
            $error["groupId"] = "Chọn nhóm chức năng";
            $error["groupName"] = "Hoặc tự nhập tên chức năng mới";
        }
        if (TextUtil::getVariable($form, "groupPosition") == null) {
            $form->groupPosition = 0;
        }

        if ($form->actions == null || empty($form->actions)) {
            $form->actions = [];
//            return new Response(false, "Chức năng chưa được map, thông tin hành động chưa được nhập", $error);
        }

        if (!empty($error)) {
            return new Response(false, "Map chức năng không thành công!", $error);
        }

        //Tạo nhóm
        $cpFunctionGroup = new CpFunctionGroup();
        if ($form->groupName != null && $form->groupName != '') {
            $cpFunctionGroup = $this->cpFunctionGroupModel->findByGroupName($form->groupName);
            if ($cpFunctionGroup->id != null && $cpFunctionGroup->id != '') {
                return new Response(false, "Nhóm quyền " . $form->groupName . " đã tồn tại trên hệ thống", $error);
            }
            $cpFunctionGroup->name = $form->groupName;
            $cpFunctionGroup->position = $form->groupPosition;
            $this->cpFunctionGroupModel->isave($cpFunctionGroup);
            $cpFunctionGroup->id = $this->cpFunctionGroupModel->getId();
        } else {
            $cpFunctionGroup = $this->cpFunctionGroupModel->ifindById($form->groupId);
            if ($cpFunctionGroup->id == null) {
                return new Response(false, "Nhóm quyền có mã " . $form->groupId . " không tồn tại trên hệ thống", $error);
            }
        }
        //Map chức năng
        $cpFunction = $this->cpFunctionModel->getByUri($form->uri);
        if ($cpFunction->id == null || $cpFunction->id == '') {
            $cpFunction = new CpFunction();
        }
        $id = (isset($cpFunction->id) && $cpFunction->id != null) ? $cpFunction->id : null;
        $cpFunction->groupId = $cpFunctionGroup->id;
        $cpFunction->name = $form->name;
        $cpFunction->position = $form->position;
        $cpFunction->skip = false;
        $cpFunction->uri = $form->uri;
        $cpFunction->type = CpFunctionType::ACTION;
        $this->cpFunctionModel->isave($cpFunction);
        $parentFunction = ($id != null) ? $id : $this->cpFunctionModel->getId();
        //Map hành động
        foreach ($form->actions as $action) {
            $cpFunction = $this->cpFunctionModel->getByUri($action->uri);
            if ($cpFunction->id == null || $cpFunction->id == '') {
                $cpFunction = new CpFunction();
            }
            $cpFunction->groupId = $cpFunctionGroup->id;
            $cpFunction->parent = $parentFunction;
            $cpFunction->name = $action->name;
            $cpFunction->position = $action->position;
            $cpFunction->skip = ($action->skip == 1);
            $cpFunction->uri = $action->uri;
            $cpFunction->type = CpFunctionType::SERVICE;
            $this->cpFunctionModel->isave($cpFunction);
        }
        return new Response(true, "Map chức năng thành công trên hệ thống");
    }

    /**
     * Xóa nhóm quyền theo id
     * @param type $id
     * @return \application\entity\Response
     */
    public function removeGroupById($id) {
        $parent = $this->cpFunctionModel->countByGroupId($id);
        if ($parent > 0) {
            return new Response(false, "Không thể xóa nhóm quyền, bạn hãy xóa các chức năng thuộc nhóm quyền trước");
        }
        $cri = new Criteria();
        $cri->andKey("id")->is($id);
        $this->cpFunctionGroupModel->idelete($cri);
        return new Response(true, "Nhóm quyền đã được xóa khỏi hệ thống");
    }

    /**
     * Xóa chức năng theo id
     * @param type $id
     * @return \application\entity\Response
     */
    public function removeFunction($id) {
        $cri = new Criteria();
        $cri->andKey("id")->is($id);
        $this->cpFunctionModel->idelete($cri);
        return new Response(true, "Chức năng đã được xóa khỏi hệ thống");
    }

    /**
     * Cập nhật thông tin group function cp
     * @param \application\entity\db\CpFunctionGroup $form
     * @return \application\entity\Response
     */
    public function editCpFunctionGroup(CpFunctionGroup $form) {

        $cpFunctionGroup = $this->cpFunctionGroupModel->ifindById($form->id);
        $error = [];
        if ($cpFunctionGroup == null) {
            return new Response(false, "Không tìm thấy nhóm quyền yêu cầu", $error);
        }
        if (TextUtil::getVariable($form, "name") == null) {
            $error["name"] = "Tên chức năng không được để trống";
        }
        if (TextUtil::getVariable($form, "position") == null) {
            $form->groupPosition = 0;
        }
        $cpFunctionGroup->name = $form->name;
        $cpFunctionGroup->position = $form->position;
        $this->cpFunctionGroupModel->isave($cpFunctionGroup);
        return new Response(true, "Cập nhật thành công thông tin nhóm quyền " . $cpFunctionGroup->name, $cpFunctionGroup);
    }

    /**
     * Chi tiết nhóm quyền
     * @return type
     */
    public function getCpFunctionGroupById($id) {
        $cri = new Criteria();
        $cri->andKey("id")->is($id);
        $query = new Query($cri);
        return $this->cpFunctionGroupModel->ifindOne($query);
    }

    /**
     * Chi tiết chức năng
     * @return type
     */
    public function getCpFunctionById($id) {
        $cri = new Criteria();
        $cri->andKey("id")->is($id);
        $query = new Query($cri);
        $cpFunction = $this->cpFunctionModel->ifindOne($query);
        $cri = new Criteria();
        $cri->andKey("parent")->is($id);
        $query = new Query($cri);
        $cpFunction->actions = $this->cpFunctionModel->ifind($query);
        return $cpFunction;
    }

    /**
     * Chi tiết function theo uri
     * @param type $uri
     * @return type
     */
    public function getFunctionByUri($uri) {
        $cri = new Criteria();
        $cri->andKey("uri")->is($uri);
        $query = new Query($cri);
        return $this->cpFunctionModel->ifindOne($query);
    }

}
